﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Lswweb.Domain;
using Lswweb.Common;

namespace Lswweb.Domain.ResourceConfiguration
{
    public class ResourceMaps : ResourceBase<MapType, IDictionary<string, MapNode>>
    {
        #region 字段和构造方法

        private IResource strings;
        private IResource urls;

        public ResourceMaps(string filePath, IResource strings, IResource urls)
            : base(filePath) 
        {
            this.strings = strings;
            this.urls = urls;
        }

        #endregion

        protected override KeyValuePair<MapType, IDictionary<string, MapNode>> GetPairByXmlNode(System.Xml.XmlNode node)
        {
            IDictionary<string, MapNode> nodes = new Dictionary<string, MapNode>();
            MapType key = node.Attributes["name"].Value.As<MapType>();

            foreach (XmlNode childNode in node.ChildNodes)
                ReadNode(childNode, string.Empty, nodes,key);

            return new KeyValuePair<MapType, IDictionary<string, MapNode>>(key, nodes);
        }

        private void ReadNode(XmlNode xmlNode, string parentName, IDictionary<string, MapNode> nodes, MapType type)
        {
            if (xmlNode == null || xmlNode.NodeType == XmlNodeType.Comment)
                return;

            XmlAttribute name = xmlNode.Attributes["name"];
            XmlAttribute textKey = xmlNode.Attributes["textKey"];
            XmlAttribute path = xmlNode.Attributes["path"];
            XmlAttribute urlKey = xmlNode.Attributes["urlKey"];
            XmlAttribute urlQuery = xmlNode.Attributes["urlQuery"];
            XmlAttribute urlQueryPattern = xmlNode.Attributes["urlQueryPattern"];
            XmlAttribute visible = xmlNode.Attributes["visible"];
            XmlAttribute image = xmlNode.Attributes["image"];
            XmlAttribute imageAction = xmlNode.Attributes["imageAction"];

            if (name == null || textKey == null)
                throw new Exception("必须设置name标签。");

            string urlKeyValue = urlKey == null ? string.Empty : urlKey.Value;
            string urlQueryValue = urlQuery == null ? null : urlQuery.Value;
            string urlQueryPatternValue = urlQueryPattern == null ? urlQueryValue : urlQueryPattern.Value;
            string textValue = this.strings[textKey.Value] as string;
            string imageValue = image == null ? string.Empty : image.Value;
            string imageActionValue = imageAction == null ? string.Empty : imageAction.Value;
            bool visibleValue = visible == null ? true : Convert.ToBoolean(visible.Value);

            string url = BuilderUrl(urlKeyValue, urlQueryValue, null);
            string urlPattern = BuilderUrl(
                    urlKeyValue,
                    urlQueryPatternValue,
                    delegate(string urlStr)
                    {
                        //因为?在正在表达式中有特殊意义，而一般网址中用?来区分参数。所以这里要进行一下转换
                        return urlStr.Replace("?", @"\?");
                    });


            MapNode mapNode = new MapNode(
                type,
                name.Value,
                parentName,
                url,
                urlPattern,
                textValue,
                path.Value,
                imageValue,
                imageActionValue,
                visibleValue);

            if (nodes.ContainsKey(mapNode.Name))
                nodes.Remove(mapNode.Name);

            nodes.Add(mapNode.Name, mapNode);

            XmlNodeList nodeList = xmlNode.ChildNodes;
            foreach (XmlNode childNode in nodeList)
                ReadNode(childNode, mapNode.Name, nodes, type);
        }

        private string BuilderUrl(string urlKey, string urlQuery, Func<string, string> urlHandle)
        {
            if (string.IsNullOrEmpty(urlKey))
                return string.Empty;

            Url url = ((Url)this.urls[urlKey]);

            return url.BuilderUrl(
                urlHandle,
                (urlQuery == null) ? null : urlQuery.Split(','));
        }
    }
}
